import { Injectable, UnauthorizedException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { AppUser } from '../user/user.entity';
import { Repository } from 'typeorm';
import { JwtService } from '@nestjs/jwt';
import { AppUserService } from '../user/user.service';
import { dateFormat } from 'src/utils/date.util';
import jwt from 'jsonwebtoken';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class AppAuthService {
  constructor(
    @InjectRepository(AppUser)
    private readonly userRepository: Repository<AppUser>,

    private readonly jwtService: JwtService,
    private readonly appUserService: AppUserService,
    private readonly configService: ConfigService,
  ) {}

  getToken(user: AppUser) {
    const payload = {
      uid: user.userId,
      vip: user.vipLevel,
    };
    return this.jwtService.sign(payload);
  }

  async register(userId: string) {
    const user = await this.userRepository.findOne({
      where: {
        userId,
      },
    });
    if (user) {
      return {
        data: null,
        message: '用户已存在',
      };
    }
    await this.appUserService.createUser({
      vipLevel: 0,
      name: `新用户${Date.now()}`,
      vipExpiredAt: dateFormat(new Date()),
      userId,
      avatar: '',
    });
    return {
      data: null,
    };
  }

  async supabaseLogin(token: string) {
    return new Promise(async (resolve, reject) => {
      this.validateSupabaseToken(token)
        .then(async (userId) => {
          if (!userId) {
            reject(401);
          }
          const user = await this.userRepository.findOne({
            where: {
              userId,
            },
          });
          if (user) {
            resolve(this.getToken(user));
            return;
          }
          const u = await this.appUserService.createUser({
            vipLevel: 0,
            name: `新用户${Date.now()}`,
            vipExpiredAt: dateFormat(new Date()),
            userId,
            avatar: '',
            // quota: 15 * 60,
          });
          resolve(this.getToken(u));
        })
        .catch(() => {
          reject('token错误');
        });
    }).catch(() => {
      throw new UnauthorizedException('Invalid token');
    });
  }

  async validateSupabaseToken(token: string): Promise<string> {
    return new Promise((resolve, reject) => {
      try {
        jwt.verify(
          token,
          this.configService.get('SUPABASE_JWT_SECRET'),
          async (err, decoded: { sub: string }) => {
            if (err) {
              reject(err);
            } else {
              resolve(decoded.sub);
            }
          },
        );
      } catch (error) {
        reject(error);
      }
    });
  }
}
